<template>
  <div class="chat-section">
    <!-- 消息区域 -->
    <div class="messages-container" ref="messagesContainer">
      <!-- 加载更多按钮 -->
      <div v-if="hasMoreHistory" class="load-more-container">
        <a-button type="link" :loading="loadingHistory" size="small" @click="loadMoreHistory">
          加载更多历史消息
        </a-button>
      </div>
      <div v-for="(message, index) in messages" :key="index" class="message-item">
        <div v-if="message.type === 'user'" class="user-message">
          <div class="message-content">{{ message.content }}</div>
          <div class="message-avatar">
            <a-avatar :src="loginUserStore.loginUser.userAvatar" />
          </div>
        </div>
        <div v-else class="ai-message">
          <div class="message-avatar">
            <a-avatar :src="aiAvatar" />
          </div>
          <div class="message-content">
            <MarkdownRenderer v-if="message.content" :content="message.content" />
            <div v-if="message.loading" class="loading-indicator">
              <a-spin size="small" />
              <span>AI 正在思考...</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 选中元素信息展示 -->
    <a-alert
      v-if="selectedElementInfo"
      class="selected-element-alert"
      type="info"
      closable
      @close="clearSelectedElement"
    >
      <template #message>
        <div class="selected-element-info">
          <div class="element-header">
            <span class="element-tag">
              选中元素：{{ selectedElementInfo.tagName.toLowerCase() }}
            </span>
            <span v-if="selectedElementInfo.id" class="element-id">
              #{{ selectedElementInfo.id }}
            </span>
            <span v-if="selectedElementInfo.className" class="element-class">
              .{{ selectedElementInfo.className.split(" ").join(".") }}
            </span>
          </div>
          <div class="element-details">
            <div v-if="selectedElementInfo.textContent" class="element-item">
              内容: {{ selectedElementInfo.textContent.substring(0, 50) }}
              {{ selectedElementInfo.textContent.length > 50 ? "..." : "" }}
            </div>
            <div v-if="selectedElementInfo.pagePath" class="element-item">
              页面路径: {{ selectedElementInfo.pagePath }}
            </div>
            <div class="element-item">
              选择器:
              <code class="element-selector-code">{{ selectedElementInfo.selector }}</code>
            </div>
          </div>
        </div>
      </template>
    </a-alert>

    <!-- 用户消息输入框 -->
    <div class="input-container">
      <div class="input-wrapper">
        <a-tooltip v-if="!isOwner" title="无法在别人的作品下对话哦~" placement="top">
          <a-textarea
            v-model:value="userInput"
            :placeholder="getInputPlaceholder()"
            :rows="4"
            :maxlength="1000"
            :disabled="isGenerating || !isOwner"
            @keydown.enter.prevent="sendMessage"
          />
        </a-tooltip>
        <a-textarea
          v-else
          v-model:value="userInput"
          :placeholder="getInputPlaceholder()"
          :rows="4"
          :maxlength="1000"
          :disabled="isGenerating"
          @keydown.enter.prevent="sendMessage"
        />
        <div class="input-actions">
          <a-button
            type="primary"
            @click="sendMessage"
            :loading="isGenerating"
            :disabled="!isOwner"
          >
            <template #icon>
              <SendOutlined />
            </template>
          </a-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { nextTick, ref } from "vue"
import { useLoginUserStore } from "@/stores/loginUser"
import aiAvatar from "@/assets/aiAvatar.png"
import MarkdownRenderer from "./MarkdownRenderer.vue"
import { API_BASE_URL } from "@/config/env"
import request from "@/request"
import { message } from "ant-design-vue"
import { SendOutlined } from "@ant-design/icons-vue"
import type { Message } from "@/types/app"
import type { ElementInfo } from "@/utils/visualEditor"

interface Props {
  appId: string // 应用ID
  isOwner: boolean // 是否是应用的所有者
  hasMoreHistory: boolean // 是否有更多历史消息
  loadingHistory: boolean // 是否加载历史消息中
  selectedElementInfo: ElementInfo | null // 选中元素信息
  isEditMode: boolean // 是否处于编辑模式
}

const props = defineProps<Props>()

// 消息列表
const messages = defineModel<Message[]>("messages", {
  required: true
})
// 是否正在生成网站
const isGenerating = defineModel<boolean>("isGenerating", {
  required: true
})

const emit = defineEmits<{
  (e: "load-more-history"): void
  (e: "clear-selected-element"): void
  (e: "toggle-edit-mode"): void
  (e: "update-view"): void
}>()

const loginUserStore = useLoginUserStore()

// 加载更多历史消息
const loadMoreHistory = () => {
  emit("load-more-history")
}

// 清空选中元素
const clearSelectedElement = () => {
  emit("clear-selected-element")
}

// 用户输入
const userInput = ref("")
const messagesContainer = ref<HTMLElement>()

// 设置输入框占位符
const getInputPlaceholder = () => {
  if (props.selectedElementInfo) {
    // 选中元素时输入框的占位符
    return `正在编辑 ${props.selectedElementInfo.tagName.toLowerCase()} 元素，描述您想要的修改...`
  }
  return "请描述你想生成的网站，越详细效果越好哦"
}

// 发送初始消息
const sendInitialMessage = async (prompt: string) => {
  // 添加用户消息
  messages.value.push({
    type: "user",
    content: prompt
  })

  // 添加AI消息占位符
  const aiMessageIndex = messages.value.length
  messages.value.push({
    type: "ai",
    content: "",
    loading: true
  })

  await nextTick()
  scrollToBottom()

  // 开始生成
  isGenerating.value = true
  await generateCode(prompt, aiMessageIndex)
}

// 发送消息
const sendMessage = async () => {
  if (!userInput.value.trim() || isGenerating.value) {
    return
  }

  let message = userInput.value.trim()
  // 如果有选中的元素，将元素信息添加到提示词中
  if (props.selectedElementInfo) {
    let elementContext = `\n\n选中元素信息：`
    if (props.selectedElementInfo.pagePath) {
      elementContext += `\n- 页面路径: ${props.selectedElementInfo.pagePath}`
    }
    elementContext += `\n- 标签: ${props.selectedElementInfo.tagName.toLowerCase()}\n- 选择器: ${props.selectedElementInfo.selector}`
    if (props.selectedElementInfo.textContent) {
      elementContext += `\n- 当前内容: ${props.selectedElementInfo.textContent.substring(0, 100)}`
    }
    message += elementContext
  }
  userInput.value = ""
  // 添加用户消息（包含元素信息）
  messages.value.push({
    type: "user",
    content: message
  })

  // 发送消息后，清除选中元素并退出编辑模式
  if (props.selectedElementInfo) {
    clearSelectedElement()
    if (props.isEditMode) {
      emit("toggle-edit-mode")
    }
  }

  // 添加AI消息占位符
  const aiMessageIndex = messages.value.length
  messages.value.push({
    type: "ai",
    content: "",
    loading: true
  })

  await nextTick()
  scrollToBottom()

  // 开始生成
  isGenerating.value = true
  await generateCode(message, aiMessageIndex)
}

// 生成代码 - 使用 EventSource 处理流式响应
const generateCode = async (userMessage: string, aiMessageIndex: number) => {
  let eventSource: EventSource | null = null
  let streamCompleted = false

  try {
    // 获取 axios 配置的 baseURL
    const baseURL = request.defaults.baseURL || API_BASE_URL

    // 构建URL参数
    const params = new URLSearchParams({
      appId: props.appId || "",
      message: userMessage
    })

    const url = `${baseURL}/app/chat/gen/code?${params}`

    // 创建 EventSource 连接
    eventSource = new EventSource(url, {
      withCredentials: true
    })

    let fullContent = ""

    // 处理接收到的消息
    eventSource.onmessage = function (event) {
      if (streamCompleted) return

      try {
        // 解析JSON包装的数据
        const parsed = JSON.parse(event.data)
        const content = parsed.d

        // 拼接内容
        if (content !== undefined && content !== null) {
          fullContent += content
          messages.value[aiMessageIndex]!.content = fullContent
          messages.value[aiMessageIndex]!.loading = false
          scrollToBottom()
        }
      } catch (error) {
        console.error("解析消息失败:", error)
        handleError(error, aiMessageIndex)
      }
    }

    // 处理done事件
    eventSource.addEventListener("done", function () {
      if (streamCompleted) return

      streamCompleted = true
      isGenerating.value = false
      eventSource?.close()

      // 延迟更新预览，确保后端已完成处理
      setTimeout(async () => {
        emit("update-view")
      }, 1000)
    })

    // 处理business-error事件（后端限流等错误）
    eventSource.addEventListener("business-error", function (event: MessageEvent) {
      if (streamCompleted) return

      try {
        const errorData = JSON.parse(event.data)
        console.error("SSE业务错误事件:", errorData)

        // 显示具体的错误信息
        const errorMessage = errorData.message || "生成过程中出现错误"
        messages.value[aiMessageIndex]!.content = `❌ ${errorMessage}`
        messages.value[aiMessageIndex]!.loading = false
        message.error(errorMessage)

        streamCompleted = true
        isGenerating.value = false
        eventSource?.close()
      } catch (parseError) {
        console.error("解析错误事件失败:", parseError, "原始数据:", event.data)
        handleError(new Error("服务器返回错误"), aiMessageIndex)
      }
    })

    // 处理错误
    eventSource.onerror = function () {
      if (streamCompleted || !isGenerating.value) return
      // 检查是否是正常的连接关闭
      if (eventSource?.readyState === EventSource.CLOSED) {
        streamCompleted = true
        isGenerating.value = false
        eventSource?.close()

        setTimeout(async () => {
          emit("update-view")
        }, 1000)
      } else {
        handleError(new Error("SSE连接错误"), aiMessageIndex)
      }
    }
  } catch (error) {
    console.error("创建 EventSource 失败：", error)
    handleError(error, aiMessageIndex)
  }
}

// 错误处理函数
const handleError = (error: unknown, aiMessageIndex: number) => {
  console.error("生成代码失败：", error)
  messages.value[aiMessageIndex]!.content = "抱歉，生成过程中出现了错误，请重试。"
  messages.value[aiMessageIndex]!.loading = false
  message.error("生成失败，请重试")
  isGenerating.value = false
}

// 滚动到底部
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

defineExpose({
  sendInitialMessage
})
</script>

<style scoped>
.chat-section {
  flex: 2;
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.messages-container {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
  scroll-behavior: smooth;
}

.message-item {
  margin-bottom: 12px;
}

.user-message {
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 8px;
}

.ai-message {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 8px;
}

.message-content {
  max-width: 70%;
  padding: 12px 16px;
  border-radius: 12px;
  line-height: 1.5;
  word-wrap: break-word;
}

.user-message .message-content {
  background: #1890ff;
  color: white;
}

.ai-message .message-content {
  background: #f5f5f5;
  color: #1a1a1a;
  padding: 8px 12px;
}

.message-avatar {
  flex-shrink: 0;
}

.loading-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #666;
}

/* 加载更多按钮 */
.load-more-container {
  text-align: center;
  padding: 8px 0;
  margin-bottom: 16px;
}

/* 输入区域 */
.input-container {
  padding: 16px;
  background: white;
}

.input-wrapper {
  position: relative;
}

.input-wrapper .ant-input {
  padding-right: 50px;
}

.input-actions {
  position: absolute;
  bottom: 8px;
  right: 8px;
}

.selected-element-alert {
  margin: 0 16px;
}

@media (max-width: 1024px) {
  .chat-section {
    flex: none;
    height: 50vh;
  }
}

@media (max-width: 768px) {
  .message-content {
    max-width: 85%;
  }

  .selected-element-alert {
    margin: 0 16px;
  }

  .message-content {
    max-width: 85%;
  }

  .selected-element-info {
    line-height: 1.4;
  }

  .element-header {
    margin-bottom: 8px;
  }

  .element-details {
    margin-top: 8px;
  }

  .element-item {
    margin-bottom: 4px;
    font-size: 13px;
  }

  .element-item:last-child {
    margin-bottom: 0;
  }

  .element-tag {
    font-family: "Monaco", "Menlo", monospace;
    font-size: 14px;
    font-weight: 600;
    color: #007bff;
  }

  .element-id {
    color: #28a745;
    margin-left: 4px;
  }

  .element-class {
    color: #ffc107;
    margin-left: 4px;
  }

  .element-selector-code {
    font-family: "Monaco", "Menlo", monospace;
    background: #f6f8fa;
    padding: 2px 4px;
    border-radius: 3px;
    font-size: 12px;
    color: #d73a49;
    border: 1px solid #e1e4e8;
  }
}
</style>
